﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Visifire.Charts;
using System.Windows.Media.Animation;
using CPPEI.Coolzon.Common;
using System.Windows;
using System.Windows.Media;
using Visifire.Commons;
using Coolzon.UI.Common.Widgets;
using Coolzon.UI.Core;
using Coolzon.Web.Models;
using Coolzon.UI.Core.Properties;

namespace Coolzon.UI.Charts.Widgets
{
    public partial class DataChartBase : DataWidget
    {
        protected Storyboard _animationStoryboard;
        /// <summary>
        /// 记录每个DataPoint的最终值，动画结束后给每个DataPoint赋值，并清除动画
        /// </summary>
        protected Dictionary<DataPoint, double> dicDataPoitList;

        public DataChartBase()
        {
            DataPointWidth = 5;
            LegendEnabled = false;
        }

        protected override void OnInit(PartContext context)
        {
            base.OnInit(context);

            Chart chart = GetChart();

            if (chart == null)
            {
                return;
            }
            chart.ShadowEnabled = false;
            chart.LightingEnabled = false;
            chart.BorderThickness = new Thickness(0);
            chart.Background = null;
            chart.View3D = XIs3DMode;
            chart.AnimatedUpdate = false;
            chart.PlotArea = GetPlotArea();
            chart.Titles.Clear();
            chart.Titles.Add(GetTitle());
            if (DataPointWidth != null)
            {
                chart.DataPointWidth = DataPointWidth.Value;
            }
            //if (NeedUpdateLayout && chart.IsLoaded)
            //{
            //    NeedUpdateLayout = false;
            //    chart.UpdateLayout();
            //}
        }

        protected override void OnApplyXProperty()
        {
            base.OnApplyXProperty();
        }
        protected override void OnDestroy()
        {
            Chart chart = GetChart();
            chart.Series.Clear();

            if (_animationStoryboard != null)
            {
                _animationStoryboard.Stop();
                _animationStoryboard.Remove();
                _animationStoryboard = null;
            }
            base.OnDestroy();
        }

        protected override void OnDataBinding(DataBindingArgs args)
        {
            //ClearAnimation();
            //StopAnimation();
            //_animationStoryboard = new Storyboard();
            //_animationStoryboard.FillBehavior = FillBehavior.HoldEnd;
            //_animationStoryboard.Completed += _animationStoryboard_Completed;

            List<Coolzon.Web.Models.DataSeries> dataSeriesList = ResolveDataResult(args.DataResult);

            Chart chart = GetChart();
            //chart.Series.Clear();
            //if (dicDataPoitList == null)
            //{
            //    dicDataPoitList = new Dictionary<DataPoint, double>();
            //}
            //else
            //{
            //    dicDataPoitList.Clear();
            //}

            if (dataSeriesList != null && dataSeriesList.Count > 0)
            {
                if (dataSeriesList.Count < chart.Series.Count)
                {
                    // 从现有图表上移除多余的数据串
                    for (int itemIndex = dataSeriesList.Count; itemIndex < chart.Series.Count; itemIndex++)
                    {
                        chart.Series.RemoveAt(itemIndex);
                    }
                }

                for(int seriesIndex = 0; seriesIndex < dataSeriesList.Count; seriesIndex++)
                {
                    Coolzon.Web.Models.DataSeries dataSerie = dataSeriesList[seriesIndex];

                    Visifire.Charts.DataSeries vfdataSeries = null;
                    if (seriesIndex < chart.Series.Count)
                    {
                        vfdataSeries = chart.Series[seriesIndex];
                    }
                    else
                    {
                        vfdataSeries = new Visifire.Charts.DataSeries();
                        chart.Series.Add(vfdataSeries);
                    }
                    if (LineThickness != null)
                    {
                        vfdataSeries.LineThickness = LineThickness;
                    }
                    vfdataSeries.RenderAs = GetRender(dataSerie.Id);
                    vfdataSeries.Name = dataSerie.Name;
                    vfdataSeries.LegendText = dataSerie.Name;
                    vfdataSeries.Bevel = Bevel;
                    vfdataSeries.ShowInLegend = LegendEnabled;
                    ResolveVisifireDataSeries(vfdataSeries);
                    vfdataSeries.LegendMarkerType = MarkerTypes.Cross;

                    int totalItemCount = dataSerie.DataItems.Count;

                    if (dataSerie.DataItems.Count < vfdataSeries.DataPoints.Count)
                    {
                        // 从现有图表上移除多余的数据
                        for (int itemIndex = dataSerie.DataItems.Count; itemIndex < vfdataSeries.DataPoints.Count; itemIndex++)
                        {
                            vfdataSeries.DataPoints.RemoveAt(itemIndex);
                        }
                    }

                    for (int itemIndex = 0; itemIndex < totalItemCount; itemIndex++)
                    {
                        DataItem dataItem = dataSerie.DataItems[itemIndex];

                        DataPoint datapoint = null;
                        if(itemIndex < vfdataSeries.DataPoints.Count)
                        {
                            datapoint = (DataPoint)vfdataSeries.DataPoints[itemIndex];
                        }
                        else
                        {
                            datapoint = new DataPoint();
                            datapoint.YValue = 0;
                            datapoint.Name = dataItem.Name;
                            datapoint.LegendText = dataItem.Name;
                            datapoint.ShowInLegend = LegendEnabled;
                            datapoint.LegendMarkerType = MarkerTypes.Square;
                            SetDataPoint(datapoint);
                            vfdataSeries.DataPoints.Add(datapoint);
                        }

                        double dItemValue = Convert.ToDouble(dataItem.Value);
                        if(args.Reason == DataBindingReason.Active)
                        {
                            datapoint.BeginAnimation(DataPoint.YValueProperty, null);
                            datapoint.YValue = 0;
                            // active 从0 开始
                            double animationInteval = (XDataAnimationDuration) / (double)dataSerie.DataItems.Count;
                            DoubleAnimation animation = new DoubleAnimation(0, dItemValue, new Duration(TimeSpan.FromSeconds(animationInteval)));
                            animation.BeginTime = TimeSpan.FromSeconds((totalItemCount - itemIndex - 1) * animationInteval);
                            datapoint.BeginAnimation(DataPoint.YValueProperty, animation, HandoffBehavior.SnapshotAndReplace);
                        }
                        else
                        {
                            DoubleAnimation animation = new DoubleAnimation(datapoint.YValue, dItemValue, new Duration(TimeSpan.FromSeconds(XDataAnimationDuration)));
                            datapoint.BeginAnimation(DataPoint.YValueProperty, animation, HandoffBehavior.SnapshotAndReplace);
                        }
                        //dicDataPoitList.Add(datapoint, dItemValue);

                        //animation.BeginTime = TimeSpan.FromSeconds((totalItemCount - itemIndex - 1) * animationInteval);
                        //Storyboard.SetTarget(animation, datapoint);
                        //Storyboard.SetTargetProperty(animation, new PropertyPath(DataPoint.YValueProperty));
                        //_animationStoryboard.Children.Add(animation);
                    }
                }

                //if (_animationStoryboard != null)
                //{
                //    _animationStoryboard.Begin();
                //}
            }

            SetLegends(chart.Legends);

            ApplyChartColorPlate();
        }

        /// <summary>
        /// 动画完成事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void _animationStoryboard_Completed(object sender, EventArgs e)
        {
            ClearAnimation();
            //给DataPoint赋最终值并清除动画
            if (dicDataPoitList != null && dicDataPoitList.Count > 0)
            {
                foreach (var item in dicDataPoitList)
                {
                    try
                    {
                        item.Key.YValue = item.Value;
                    }
                    catch (Exception ex)
                    {

                    }
                }
                dicDataPoitList.Clear();
            }
            StopAnimation();
        }

        protected virtual void ApplyChartColorPlate()
        {

        }

        /// <summary>
        /// 清理动画，清理故事版中每个动画的target，防止内存溢出
        /// </summary>
        protected void ClearAnimation()
        {
            if (_animationStoryboard != null)
            {
                foreach (Timeline tl in _animationStoryboard.Children)
                {
                    tl.ClearValue(Storyboard.TargetProperty);
                }
            }
        }
        protected void StopAnimation()
        {
            if (_animationStoryboard != null)
            {
                _animationStoryboard.Completed -= _animationStoryboard_Completed;
                _animationStoryboard.Stop();
                _animationStoryboard.Remove();
                _animationStoryboard = null;
            }
        }
        protected virtual Chart GetChart()
        {
            return null;
        }
        protected virtual RenderAs GetRender(string dataSeriesId)
        {
            return RenderAs.Column;
        }

        protected virtual void ResolveVisifireDataSeries(Visifire.Charts.DataSeries dataSeries)
        {
        }

        /// <summary>
        /// 处理数据，每个图表可能有自己相关的数据
        /// </summary>
        /// <param name="dataResult"></param>
        /// <returns></returns>
        protected virtual List<Coolzon.Web.Models.DataSeries> ResolveDataResult(Coolzon.Web.Models.DataResult dataResult)
        {
            return dataResult.DataSeries;
        }
    }
}
